package com.king.pages.novel.service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.king.db.DBTool;
import com.king.mind.VolumeNode;
import com.king.pages.novel.dao.NovelDao;
import com.king.pages.novel.entity.Chapter;
import com.king.pages.novel.entity.ChapterLabel;
import com.king.pages.novel.entity.Novel;
import com.king.pages.novel.entity.NovelVolume;
import com.king.util.DateTool;
import com.king.util.exception.KingException;
import com.king.util.ids.IDS;

import ch.qos.logback.core.util.StringUtil;
import jakarta.annotation.PostConstruct;

/**
 * 书-service
 * 
 * @author king
 * @date 2025年6月25日-15:05:46
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class NovelService extends DBTool {

	private final static String CHAPTER = "chapter-id";

	private final static String NOVEL = "novel-id";

	private final static String VOLUME = "volume-id";

	@Autowired
	private NovelDao novelDao;

	@PostConstruct
	public void init() throws KingException {
		// 初始章节的IDS工具，默认长度是6个字符
		IDS.build(CHAPTER, (ids) -> {
			return novelDao.existsChapterIds(ids);
		});
		IDS.build(NOVEL, (ids) -> {
			return novelDao.existsNovelIds(ids);
		});
		IDS.build(VOLUME, (ids) -> {
			return novelDao.existsVolumeIds(ids);
		});
	}

	/**
	 * 分页
	 * 
	 * @param novel
	 * @return
	 * @author king
	 * @throws Exception
	 * @date 2025年6月26日-10:19:50
	 */
	public List<Map<String, Object>> selNovelPage(Novel novel) throws Exception {
		return page(novel, novelDao);
	}

	/**
	 * 加载数据的数据，结构如：[novelVolume:[chapter]]
	 * 
	 * @param bookId
	 * @return
	 * @author king
	 * @date 2025年7月8日-17:55:53
	 */
	public List<VolumeNode> loadBookData(String bookId) {
		return novelDao.loadBookData(bookId);
	}

	/**
	 * 获取章节信息
	 * 
	 * @param chapterId
	 * @return
	 */
	public Chapter selChapterInfo(String chapterId) {
		return novelDao.selChapterInfo(chapterId);
	}

	/**
	 * 保存/添加章节数据
	 * 
	 * @param ch
	 * @return
	 * @author king
	 * @throws KingException
	 * @date 2025年7月16日-18:04:29
	 */
	public boolean save(Chapter ch) throws Exception {
		Chapter db = selectOne(ch);
		if (db == null) {
			KingException.build("无效章节ID");
		}
		ch.setNum(db.getNum());
		ch.setCreateDate(db.getCreateDate());

		ChapterLabel cl = new ChapterLabel();
		cl.setChapterId(ch.getId());
		delete(cl, new String[] { "chapter_id" });
		if (ch.labels() != null) {
			insertBatch(ch.labels());
		}

		return update(ch, new String[] { "description", "title", "word" }, "id") > 0;
	}

	/**
	 * 添加章节
	 * 
	 * @param <T>
	 * @param currentNovelId
	 * @return
	 * @author king
	 * @throws Exception
	 * @date 2025年7月17日-16:12:58
	 */
	public Chapter addNovel(String currentNovelId) throws Exception {
		Chapter c = new Chapter();
		c.setTitle("新章节");
		c.setId(IDS.get(CHAPTER));
		c.setNovelId(currentNovelId);
		c.setCreateDate(LocalDateTime.now());
		Chapter db = selectOne(c, new String[] { "title", "num" }, new String[] { "novel_id" }, "num DESC");
		if (db == null) {
			c.setNum(1);
		} else {
			c.setNum(db.getNum() + 1);
		}
		NovelVolume nv = new NovelVolume();
		nv.setNovelId(currentNovelId);

		nv = selectOne(nv, new String[] { "id" }, new String[] { "novel_id" }, "create_date DESC");
		if (nv == null) {
			KingException.build("卷数据异常");
		}
		c.setNovelVolumeId(nv.getId());
		if (insert(c) <= 0) {
			KingException.build("创建失败");
		}
		return c;
	}

	/**
	 * 删除本书的最后一章，并返回被删除章节的ID
	 * 
	 * @param novelId
	 * @return
	 * @author king
	 * @throws Exception
	 * @date 2025年7月22日-09:51:36
	 */
	public String delLastChapter(String novelId) throws Exception {
		Chapter c = new Chapter();
		c.setNovelId(novelId);
		c = selectOnee(c, new String[] { "id", "word" }, "novel_id", "num DESC");
		if (c == null) {
			KingException.build("本书下未找到章节信息！");
		}
		if (!StringUtil.isNullOrEmpty(c.getWord())) {
			KingException.build("请先手动清空最后一章的内容！");
		}

		ChapterLabel labels = new ChapterLabel();
		labels.setChapterId(c.getId());
		if (count(labels, new String[] { "chapter_id" }) > 0) {
			KingException.build("请先手动清空该章节下的标签数据！");
		}
		if (delete(c) <= 0) {
			KingException.build("删除失败！");
		}
		return c.getId();
	}

	/**
	 * 查询书的基本信息，含卷数据
	 * 
	 * @param novelId
	 * @return
	 * @throws Exception
	 * @author king
	 * @date 2025年7月22日-17:44:21
	 */
	public Novel loadBookBaseInfo(String novelId) throws Exception {
		Novel n = new Novel();
		n.setId(novelId);
		n = selectOne(n, new String[] { "id", "name", "writer", "description" });
		if (n == null) {
			KingException.build("书ID数据异常");
		}
		NovelVolume nv = new NovelVolume();
		nv.setNovelId(novelId);
		List<NovelVolume> nvs = select(nv, null, new String[] { "novel_id" });
		if (nvs != null) {
			n.setVolume(nvs);
		}
		return n;
	}

	/**
	 * 保存或添加书的基本信息
	 * 
	 * @param novel
	 * @return
	 * @author king
	 * @throws Exception
	 * @date 2025年7月23日-10:04:29
	 */
	public boolean saveNovel(Novel novel) throws Exception {
		if (StringUtil.isNullOrEmpty(novel.getId())) {
			return addNovel(novel);
		}
		return editNovel(novel);
	}

	/**
	 * 添加书
	 * 
	 * @param novel
	 * @return
	 * @author king
	 * @throws Exception
	 * @date 2025年7月23日-10:10:14
	 */
	private boolean addNovel(Novel novel) throws Exception {
		novel.setStatus(1);
		novel.setId(IDS.get(NOVEL));
		novel.setCreateDate(DateTool.now());

		if (novel.getVolume() != null && novel.getVolume().size() > 0) {
			for (NovelVolume v : novel.getVolume()) {
				v.setId(IDS.get(VOLUME));
				v.setNovelId(novel.getId());
				v.setCreateDate(novel.getCreateDate());
			}
			if (insertBatch(novel.getVolume()) <= 0) {
				KingException.build("章节数据存储失败！");
			}
		}
		return insert(novel) > 0;
	}

	/**
	 * 编辑书
	 * 
	 * @param novel
	 * @return
	 * @author king
	 * @throws Exception
	 * @date 2025年7月23日-10:10:02
	 */
	private boolean editNovel(Novel novel) throws Exception {
		int i = update(novel, new String[] { "name", "writer", "description" });
		if (i <= 0) {
			KingException.build("书的信息存储失败！");
		}
		NovelVolume vdb = new NovelVolume();
		vdb.setNovelId(novel.getId());
		if (novel.getVolume() != null && novel.getVolume().size() > 0) {
			// 处理哪些是加的，哪些是要编辑的
			List<NovelVolume> add = novel.getVolume().stream().filter(a -> StringUtil.isNullOrEmpty(a.getId()))
					.toList();
			novel.getVolume().removeAll(add);
			// 除了要添加的，剩下的就是要剪辑的
			List<NovelVolume> edit = novel.getVolume();
			// 数据库中有，但是参数中没有，那么应该要删除数据库中的

			List<NovelVolume> db = select(vdb, null, new String[] { "novel_id" });
			if (db.size() > 0) {
				List<String> paramIds = edit.stream().map(NovelVolume::getId).toList();
				List<NovelVolume> del = db.stream().filter((e) -> !paramIds.contains(e.getId())).toList();
				if (del.size() > 0 && novelDao.delBatchVolume(del) <= 0) {
					KingException.build("删除卷数据失败！");
				}
				// 剩下的才是要更新的
				edit.removeAll(del);
			}
			if (add.size() > 0) {
				for (NovelVolume v : add) {
					v.setId(IDS.get(VOLUME));
					v.setCreateDate(DateTool.now());
				}
				if (insertBatch(add) <= 0) {
					KingException.build("卷数据插入失败！");
				}
			}
			if (edit.size() > 0) {
				// 当前版本sqlite不支持批量更新，所以只能一条一条的更新，循环着来
				String[] values = { "title", "description" };
				for (NovelVolume nv : edit) {
					if (update(nv, values) <= 0) {
						KingException.build("卷数据更新失败！");
					}
				}
			}
		} else {
			// 如果传入的卷数据是空的，那么不管三七二十一，先执行一个删除本书下的卷数据在说
			delete(vdb, new String[] { "novel_id" });
		}
		return true;
	}

	/**
	 * 启用，禁用Novel
	 * 
	 * @param novel
	 * @return
	 * @author king
	 * @throws Exception
	 * @date 2025年7月23日-14:37:27
	 */
	public boolean enableNovel(Novel novel) throws Exception {
		novel.setStatus(novel.getStatus() == 1 ? 0 : 1);
		return update(novel, new String[] { "status" }) > 0;
	}

}
